#ifndef NRPSTG_CAMERA_H
#define NRPSTG_CAMERA_H

#include <string>
#include <SDL.h>
#include <boost/unordered_map.hpp>
#include <boost/tuple/tuple.hpp>
#include <assimp.h>

using namespace std;
using namespace boost;

class CameraMode {
private:
    aiMatrix4x4* _matrix;

    aiVector3D* _rotate;
    aiVector3D* _zoom;
    aiVector3D* _translate;

    aiVector3D* _rotate_vec;
    aiVector3D* _zoom_vec;
    aiVector3D* _translate_vec;

    double _rotate_speed;
    double _zoom_speed;
    double _translate_speed;

    aiVector3D* _rotate_min;
    aiVector3D* _rotate_max;

    aiVector3D* _zoom_min;
    aiVector3D* _zoom_max;

    aiVector3D* _translate_min;
    aiVector3D* _translate_max;

    double _mouse_sensitivity;

    unordered_map<SDLKey, tuple<aiVector3D*, aiVector3D> > _key_handlers;

    void _update_rotate(unsigned int ms);
    void _update_translate(unsigned int ms);
    void _update_zoom(unsigned int ms);

public:
    CameraMode();
    virtual ~CameraMode();

    void rotate_camera(aiVector3D* vec);
    void translate_camera(aiVector3D* vec);
    void zoom_camera(aiVector3D* vec);

    void resume();
    void pause();
    void apply();

    void input(SDL_Event* evt, unsigned int ms);
    void update(unsigned int ms);
};

class Camera {
private:
    CameraMode* _current_mode;
    unordered_map<string, CameraMode*> _modes;

public:
    Camera();
    virtual ~Camera();

    void set_mode(string mode);
    void apply_camera_transform();
    void input(SDL_Event* evt, unsigned int ms);
    void update(unsigned int ms);

};

#endif